﻿// This File is part of Innovation Foundry's "QualityHelper Project"
//
// Copyright  2009 Innovation Foundry Pty Ltd
// All rights reserved
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA  02110-1301 USA
// or alternatively it may be downloaded from <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using System.Windows.Browser;
using System.ComponentModel;
using System.Collections.ObjectModel;
using InnovationFoundry.QualityHelper.Utilities;

namespace InnovationFoundry.QualityHelper.Silverlight.BLL.Objects
{
    [ScriptableType]
	[DataContract]
    public class ProcedureObject : ISLBLLObject, INotifyPropertyChanged , IHasID
    {

        private ObservableCollectionWithID<ProcedureObject> children = new ObservableCollectionWithID<ProcedureObject>();

        public ObservableCollectionWithID<ProcedureObject> Children {
            get { return children; }
            set {
                if (this.children != value) {
                    this.children = value;
                    if (this.children != null)
                        children.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(children_CollectionChanged);
                    OnPropertyChanged("Children");
                }
            }
        }

        private ProcedureObject parent;

        public ProcedureObject Parent
        {
            get { return parent; }
            set
            {
                if (this.parent != value)
                {
                    this.parent = value;
                    OnPropertyChanged("Parent");
                }
            }
        }

        private string parentID;

        public string ParentID
        {
            get { return parentID; }
            set
            {
                if (this.parentID != value)
                {
                    this.parentID = value;
                    OnPropertyChanged("ParentID");
                }
            }
        }


        private string procedureID;

        public string ProcedureID
        {
            get { return procedureID; }
            set {
                if (this.procedureID != value) {
                    this.procedureID = value;
                    OnPropertyChanged("ProcedureID");
                }
            }
        }

        public object ID
        {
            get { return procedureID; }
        }

        private string procedureName;

        public string ProcedureName
        {
            get { return procedureName; }
            set {
                if (this.procedureName != value) {
                    this.procedureName = value;
                    OnPropertyChanged("ProcedureName");
                }
            }
        }

       
        private string procedureDescription;

        public string ProcedureDescription
        {
            get { return procedureDescription; }
            set {
                if (this.procedureDescription != value) {
                    this.procedureDescription = value;
                    OnPropertyChanged("ProcedureDescription");
                }
            }
        }
        
        
        private PurposeObject purpose;

        public PurposeObject Purpose
        {
            get { return purpose; }
            set {
                if (this.purpose != value) {
                    this.purpose = value;
                    OnPropertyChanged("Purpose");
                }
            }
        }

        
        private List<ProcedureAliasesObject> aliases;

        public List<ProcedureAliasesObject> Aliases
        {
            get { return aliases; }
            set {
                if (this.aliases != value) {
                    this.aliases = value;
                    OnPropertyChanged("Aliases");
                }
            }
        }

        private List<GroupObject> groups;

        public List<GroupObject> Groups
        {
            get { return groups; }
            set {
                if (this.groups != value) {
                    this.groups = value;
                    OnPropertyChanged("Groups");
                }
            }
        }
      

        private List<ConnectionObject> inboundConnections;
        public List<ConnectionObject> InboundConnections
        {
            get { return inboundConnections; }
            set {
                if (this.inboundConnections != value) {
                    this.inboundConnections = value;
                    OnPropertyChanged("InboundConnections");
                }
            }
        }

        private List<ConnectionObject> outboundConnections;
        public List<ConnectionObject> OutboundConnections
        {
            get { return outboundConnections; }
            set {
                if (this.outboundConnections != value) {
                    this.outboundConnections = value;
                    OnPropertyChanged("OutboundConnections");
                }
            }
        }

        public void AddOutboundConnection(ConnectionObject connection) {
            this.OutboundConnections.Add(connection);
            OnPropertyChanged("OutboundConnections");

        }

        public void AddInboundConnection(ConnectionObject connection) {
            this.InboundConnections.Add(connection);
            OnPropertyChanged("InboundConnections");
        }


        private List<ReferenceObject> inboundReferences;
        public List<ReferenceObject> InboundReferences
        {
            get { return inboundReferences; }
            set
            {
                if (this.inboundReferences != value)
                {
                    this.inboundReferences = value;
                    OnPropertyChanged("InboundReferences");
                }
            }
        }

        private List<ReferenceObject> outboundReferences;
        public List<ReferenceObject> OutboundReferences
        {
            get { return outboundReferences; }
            set
            {
                if (this.outboundReferences != value)
                {
                    this.outboundReferences = value;
                    OnPropertyChanged("OutboundReferences");
                }
            }
        }

        public void AddOutboundReference(ReferenceObject reference)
        {
            this.OutboundReferences.Add(reference);
            OnPropertyChanged("OutboundReferences");

        }

        public void AddInboundReference(ReferenceObject reference)
        {
            this.InboundReferences.Add(reference);
            OnPropertyChanged("InboundReferences");
        }
        
        public ProcedureObject() {
            this.OutboundReferences = new List<ReferenceObject>();
            this.InboundReferences = new List<ReferenceObject>();
            this.InboundConnections = new List<ConnectionObject>();
            this.OutboundConnections = new List<ConnectionObject>();
            this.Groups = new List<GroupObject>();
            this.Aliases = new List<ProcedureAliasesObject>();
        }

        void children_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            OnPropertyChanged("Children");
        }

        public ProcedureObject(string procedureID, string procedureName, string procedureDescription, PurposeObject purpose, GroupObject defaultProcedureGroup) : this()
        {
            this.ProcedureID = procedureID;
            this.ProcedureName = procedureName;
            this.procedureDescription = procedureDescription;
            this.Purpose = purpose;
            this.Groups.Add(defaultProcedureGroup);
        }

        public ProcedureObject(ProcedureObject procedure) : this()
        {
            this.ProcedureID = procedure.ProcedureID;
            this.ProcedureName = procedure.ProcedureName;
            this.procedureDescription = procedure.procedureDescription;
            this.Purpose = procedure.Purpose;
            foreach (GroupObject gr in procedure.Groups)
                this.Groups.Add(new GroupObject(gr.GroupName));
            foreach (ConnectionObject inCxn in procedure.InboundConnections)
                this.InboundConnections.Add(new ConnectionObject(inCxn.ProcedureOrigin,inCxn.ProcedureDestination,inCxn.ConnectionType));
            foreach (ConnectionObject outCxn in procedure.OutboundConnections)
                this.OutboundConnections.Add(new ConnectionObject(outCxn.ProcedureOrigin,outCxn.ProcedureDestination,outCxn.ConnectionType));
        }


        /// <summary>
        ///     Called when the value of a property changes.
        /// </summary>
        /// <param name="propertyName">The name of the property that has changed.</param>
        protected virtual void OnPropertyChanged(String propertyName) {
            if (String.IsNullOrEmpty(propertyName)) {
                return;
            }
            if (PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        ///     Raised when the value of one of the properties changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;


    }
}
